﻿using System;
using System.Net;
using System.Linq;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Windows;
using System.Text;

namespace 
#if WINDOWS_PHONE
    PServiceBus.WindowsPhone
#else
  PServiceBus.Silverlight
#endif
{
    internal static class SecurityElement {
        static readonly char[] s_tagIllegalCharacters = new char[] { ' ', '<', '>' };
        static readonly char[] s_textIllegalCharacters = new char[] { '<', '>' };
        static readonly char[] s_valueIllegalCharacters = new char[] { '<', '>', '"' };
        static readonly string[] s_escapeStringPairs = new string[] { "<", "&lt;", ">", "&gt;", "\"", "&quot;", "'", "&apos;", "&", "&amp;" };
        static readonly char[] s_escapeChars = new char[] { '<', '>', '"', '\'', '&' };

        private static string GetEscapeSequence(char c) {
            int length = s_escapeStringPairs.Length;
            for (int i = 0; i < length; i += 2) {
                string str = s_escapeStringPairs[i];
                string str2 = s_escapeStringPairs[i + 1];
                if (str[0] == c) {
                    return str2;
                }
            }
            return c.ToString();
        }

        public static string Escape(this string str) {
            if (str.Contains("<") ||
                   str.Contains(">") ||
                   str.Contains("'") ||
                   str.Contains("\"") ||
                   str.Contains("&"))
                return SecurityElement.__Escape(str);
            return str;
        }

        private static string __Escape(string str) {
            if (str == null) {
                return null;
            }
            StringBuilder builder = null;
            int length = str.Length;
            int startIndex = 0;
            while (true) {
                int num2 = str.IndexOfAny(s_escapeChars, startIndex);
                if (num2 == -1) {
                    if (builder == null) {
                        return str;
                    }
                    builder.Append(str, startIndex, length - startIndex);
                    return builder.ToString();
                }
                if (builder == null) {
                    builder = new StringBuilder();
                }
                builder.Append(str, startIndex, num2 - startIndex);
                builder.Append(GetEscapeSequence(str[num2]));
                startIndex = num2 + 1;
            }
        }


    }

    internal class RestHelper {

        private static string ToJson(object value) {
            if (value == null) return "null";
            var type = value.GetType();
            if (typeof(string) == type || typeof(decimal) == type ||
                type.IsPrimitive || Convert.GetTypeCode(value) != TypeCode.Object) return value.ToString();
            return value.ToJson();
        }

        public static IAsyncResult Invoke(string methodName, Dictionary<string, object> value, Action<string> action = null) {
            var result = string.Empty;
            var url = String.Format("{0}{1}?ReThrowException={2}&ESBUserName={3}&ESBPassword={4}&ConnectionID={5}", PSBClient.Endpoint,
                methodName, PSBClient.ThrowException, PSBClient.ApiKey, PSBClient.PassCode, PSBClient.UserName);
            var client = WebRequest.Create(url);
            client.Method = "POST";
            client.ContentType = "application/json";

            return client.BeginGetRequestStream(r => {

                using (var stream = client.EndGetRequestStream(r)) {
                    using (var sw = new StreamWriter(stream)) {
                        sw.Write(value.ToJson());
                        sw.Flush();
                    }
                }

                client.BeginGetResponse(res =>
                {
                    if (res.IsCompleted) {
                        var response = client.EndGetResponse(res);
                        using (var sr = new StreamReader(response.GetResponseStream()))
                            result = sr.ReadToEnd();
                    }
                    if (action != null) {
                        result = String.IsNullOrEmpty(result) ? string.Empty :
                            result.Substring(1, Math.Max(result.Length - (result.StartsWith("[") ? 1 : 2), 0)).Replace("\\\"", "\"");
                        Deployment.Current.Dispatcher.BeginInvoke(action, result);
                    }
                }, null);
            }, null);
        }
    }
}
